home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / msg / msg6.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-11  |  6.3 KB  |  303 lines

  1. /*
  2.  *            M S G 6 . C
  3.  *
  4.  * Functions -
  5.  *    smtpdate    Converts RFC822 date string to UNIX long
  6.  *    sunday        Deleted in conversion to standard timezone
  7.  *            routines - ECB 10/88
  8.  *    eatwhite    Returns first nonwhitespace char in string
  9.  *    match
  10.  *    tzset        Deleted in conversion to standard timezone
  11.  *            routines - ECB 10/88
  12.  *    makedate    Convert UNIX time to string
  13.  *
  14.  *
  15.  *        R E V I S I O N   H I S T O R Y
  16.  *
  17.  *    07/08/84  HAW    Created this module for time stamp processing.
  18.  *            Most routines in this module were written
  19.  *            by Ron Natelie.
  20.  *
  21.  */
  22. #include "util.h"
  23. #include "mmdf.h"
  24.  
  25. extern    long    atol();
  26. extern    char    *ctime();
  27.  
  28. /*
  29.  *  S M T P _ D A T E
  30.  *
  31.  *  Take an RFC822 (more or less) date string cp and convert it to
  32.  *  unix time.  Allows a variety of illegal formats commonly in use.
  33.  *
  34.  */
  35.  
  36. #define    SPACE    ' '
  37. #define    HTAB    '\t'
  38.  
  39. long    match();
  40.  
  41. /*
  42.  *  Matchtab structure.
  43.  *  Used by match routine.
  44.  */
  45. struct    match_tab  {
  46.     char    *t_string;        /*  String to match, NULL for last.  */
  47.     long    t_val;            /*  Value to be returned.  */
  48. };
  49.  
  50. /*
  51.  *  Month tab matches month names to number.
  52.  */
  53. struct    match_tab    month_tab[]  =  {
  54.     "jan", 1,    "feb", 2,    "mar", 3,    "apr", 4,
  55.     "may", 5,    "jun", 6,    "jul", 7,    "aug", 8,
  56.     "sep", 9,    "oct", 10,    "nov", 11,    "dec", 12,
  57.     NULL, 0
  58. };
  59.     
  60. #define    H(x)    ( (x)*60L*60L)
  61. struct    match_tab    zone_tab[] = {
  62.     "ut", 0,    "gmt", 0,    "est", H(-5),    "edt", H(-4),
  63.     "cst", H(-6),    "cdt", H(-5),    "mst", H(-7),    "mdt", H(-6),
  64.     "pst", H(-8),    "pdt", H(-7),    "met", H(1),    "z", 0,
  65.     "a", H(-1),    "b", H(-2),    "c", H(-3),    "d", H(-4),
  66.     "e", H(-5),    "f", H(-6),    "g", H(-7),    "h", H(-8),
  67.     "i", H(-9),    "k", H(-10),    "l", H(-11),    "m", H(-12),
  68.     "n", H(1),    "o", H(2),    "p", H(3),    "q", H(4),
  69.     "r", H(5),    "s", H(6),    "t", H(7),    "u", H(8),
  70.     "v", H(9),    "w", H(10),    "x", H(11),    "y", H(12),
  71.     NULL, 1
  72. };
  73.  
  74. #define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
  75. #define    dysize(A) (isleap(A) ? 366: 365)
  76.  
  77. static int dmsize[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  78. extern char *index();
  79. extern char *eatwhite();
  80.  
  81. long
  82. smtpdate(cp)
  83.     register char    *cp;
  84. {
  85.     struct    tm    *loctime;
  86.     int    day, month, year, hours, minutes, seconds;
  87.     int    dayno;
  88.     long    tval;
  89.     int    i;
  90.     char    *dp;
  91.     time_t    zone, tloc, time();
  92.  
  93. /*printf("S entry - date str: %s", cp); */
  94.     cp = eatwhite(cp);
  95.     dp = cp;
  96.  
  97.  
  98.     /*
  99.      *  Look for digit, supposed to be day of the month, skipping
  100.      *  over day of the week stuff.
  101.      */
  102.     while(1)  {
  103.         if(*cp == 0)  goto bad_date;
  104.         if(isdigit(*cp)) break;
  105.         cp++;
  106.     }
  107.  
  108.     day = atoi(cp);
  109. /*printf("S day: %d\n",day); */
  110.     /*  Skip digits and white space to get to month.  */
  111.  
  112.     while(isdigit(*cp)) cp++;
  113.     while( *cp == SPACE || *cp == HTAB || *cp == '-') cp++;
  114.  
  115.     month = (int)match(month_tab, cp, 3);
  116.     if(month == 0)  {
  117.         /*  Hack here, look for ctime format.  */
  118.         day = atoi(&dp[8]);
  119.         month = (int)match(month_tab, &dp[4], 3);
  120.         if(month == 0) goto bad_date;
  121.         year = atoi(&dp[20]);
  122.         hours = atoi(&dp[11]);
  123.         minutes = atoi(&dp[14]);
  124.         seconds = atoi(&dp[17]);
  125.         zone = -1;
  126. /*printf("S ctime for: y: %d m: %d d: %d h: %d m: %d s: %d\n",year,month,day,hours,minutes,seconds); */
  127.  
  128.     }
  129.     else  {
  130.         /*  Skip over to the year  */
  131.         while(1)  {
  132.             if(*cp == 0)  goto bad_date;
  133.             if(isdigit(*cp)) break;
  134.             cp++;
  135.         }
  136.         year = atoi(cp);
  137.  
  138.         while(isdigit(*cp)) cp++;
  139.  
  140.         while(*cp && !isdigit(*cp)) cp++;
  141.     
  142.  
  143.         /*  Hours, minutes, seconds  */
  144.         hours = atoi(cp);
  145.         if(hours > 60)  {
  146.             minutes = hours %100;
  147.             hours = hours/100;
  148.         }  else  {
  149.             cp = index(cp, ':');
  150.             if(cp == NULL) goto bad_date;
  151.             minutes = atoi(++cp);
  152.         }
  153.  
  154.         dp = index(cp, ':');
  155.         if(dp)  {
  156.             seconds = atoi(++dp);
  157.             cp = dp;
  158.         }
  159.         else    seconds = 0;
  160. /*printf("S hours: %d  mins: %d  secs: %d\n",hours,minutes,seconds); */
  161.         while(isdigit(*cp)) cp++;
  162.         cp = eatwhite(cp);
  163. /*printf("S Zone starts- str: %s",cp); */
  164.         if( (*cp == '+' || *cp == '-')  &&
  165.            isdigit(cp[1]) &&
  166.            isdigit(cp[2]) &&
  167.            isdigit(cp[3]) &&
  168.            isdigit(cp[4])
  169.         )  {
  170.             zone = (time_t)(atol(cp+3) * 60L);
  171.             cp[3] = 0;
  172.             zone *= (time_t)atol(cp);
  173.         } else {
  174.             if( *cp == '+' || *cp == '-' )
  175.                 cp++;
  176.             dp = cp;
  177.             while(isalpha(*cp)) cp++;
  178.             *cp = 0;
  179.             zone = (time_t)(-match(zone_tab, dp, 0));
  180.         }
  181. /*printf("S zone: %d\n",zone); */
  182.     }
  183.     if(year < 1900) year += 1900;
  184.     if(month < 1 || month > 12)  goto bad_date;
  185.     if(day < 1 || day > 31) goto bad_date;
  186.     if(hours == 24)  {
  187.         hours = 0;
  188.         day++;
  189.     }
  190.     if(hours < 0 || hours > 23) goto bad_date;
  191.     if(minutes < 0 || minutes > 59) goto bad_date;
  192.     if(seconds < 0 || seconds > 59) goto bad_date;
  193.  
  194.     tval = 0;
  195.     dayno = 0;
  196.     for(i = 1970; i < year; i++)
  197.         tval += dysize(i);
  198.  
  199.     if(isleap(year) && month >= 3)
  200.         dayno += 1;
  201.     while(--month) dayno += dmsize[month-1];
  202.     tval += dayno;
  203.     tval += day-1;
  204.     tval *= 24;
  205.     tval += hours;
  206.     tval *= 60;
  207.     tval += minutes;
  208.     tval *= 60;
  209.     tval += seconds;
  210.     if(zone == -1)  {
  211.         /*
  212.          * Determine our offset from GMT by taking the difference
  213.          * of localtime() and gmtime().
  214.          *
  215.          * Note: zone is now computed in hours and then converted
  216.          * to seconds.
  217.          */
  218.         (void) time(&tloc);
  219.         loctime = localtime(&tloc);
  220.         zone = loctime->tm_hour;         
  221.         if (loctime->tm_isdst) {
  222. /*printf("S changing zone for daylight\n"); */
  223.             zone -= 1L;
  224.         }
  225.         zone = (gmtime(&tloc)->tm_hour - zone) * 3600L;
  226. /*printf("S timezone: %d  dayno: %d\n",zone,dayno); */
  227.     }
  228. /*printf("S before zone: %s",ctime(&tval)); */
  229.     tval += zone;
  230. /*printf("S after zone: %s\n",ctime(&tval)); */
  231.     return tval;
  232.  
  233. bad_date:
  234.     return -1L;
  235. }
  236.  
  237. /*
  238.  *  E A T W H I T E
  239.  *
  240.  *  An old favorite, returns the first non whitespace in the string.
  241.  */
  242. char *
  243. eatwhite(cp)
  244.     register char *cp;
  245. {
  246.     while(*cp == SPACE || *cp == HTAB) cp++;
  247.     return cp;
  248. }
  249.  
  250. long
  251. match(tab, string, size)
  252.     register struct    match_tab    *tab;
  253.     char    *string;
  254.     int    size;
  255. {
  256.     register char *cp, *str;
  257.     char    *bufend;
  258.     char    buffer[512];
  259.     
  260.     bufend = &buffer[ (size == 0) ? 512 : size];
  261.     for(cp = buffer, str = string; cp < bufend; cp++, str++)  {
  262.         if(isupper(*str)) *cp = tolower(*str);
  263.         else    *cp = *str;
  264.         if(*cp == 0) break;
  265.     }
  266.  
  267.     while(tab->t_string != NULL)  {
  268.         if(size)  {
  269.             if(strncmp(buffer,tab->t_string, size) == 0)
  270.                 break;
  271.         }  else  {
  272.             if(strcmp(buffer, tab->t_string) == 0)
  273.                 break;
  274.         }
  275.         tab++;
  276.     }
  277.     return tab->t_val;
  278. }
  279.  
  280. /*
  281.  *            M A K E D A T E
  282.  *
  283.  * Convert UNIX date to string (DD MMM YY)
  284.  */
  285. makedate( date, dest )
  286. long    *date;
  287. char    *dest;
  288. {
  289.     char *cp;
  290.  
  291.     cp = ctime( date );
  292.      *dest++ = cp[8];
  293.      *dest++ = cp[9];
  294.      *dest++ = ' ';
  295.      *dest++ = cp[4];
  296.      *dest++ = cp[5];
  297.      *dest++ = cp[6];
  298.      *dest++ = ' ';
  299.      *dest++ = cp[22];
  300.      *dest++ = cp[23];
  301.  
  302. }
  303.